package taper.controller;

import gui.MainGUI;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import taper.controller.plc.MonitorProcessor;
import taper.controller.plc.RegisterReader;
import taper.controller.plc.TaperAdjustProcessor;
import taper.controller.polypatch.PolyPatch;
import taper.controller.wcs.TaperAverageExcelProcessor;
import taper.controller.wcs.WCSExcelProcessor;
import util.Activity;
import util.Constants;
import util.ErrorMessage;
import util.PropertiesLoader;

import db.DatabaseManager;
import db.EntityWrapper;
import db.entity.*;

public class TaperController {
	private static final Logger log = Logger.getLogger(TaperController.class);
	public static ConcurrentHashMap<String, StationStatus> activeStationMap = new ConcurrentHashMap<String, StationStatus>();
	public static ConcurrentHashMap<String, StationStatus> nonActiveStationMap = new ConcurrentHashMap<String, StationStatus>();
	//public static HashMap<String, StationConnection> connectionMap = new HashMap<String, StationConnection>();
	public static final int initialNextPadLife = 0;
	PolyPatch polyPatch;
	TaperAdjustProcessor plcControl;
	WCSExcelProcessor wcsExcel;
	TaperAverageExcelProcessor taperAverageProcessor;
	MonitorProcessor monitor;
	RegisterReader registerReader;

	public void loadStationMap() {

		StringTokenizer st1 = new StringTokenizer(
				PropertiesLoader.getActiveStation(), ",");

		while (st1.hasMoreElements()) {
			loadActiveStation((String) st1.nextElement());
		}

		StringTokenizer st2 = new StringTokenizer(
				PropertiesLoader.getNonActiveStation(), ",");

		while (st2.hasMoreElements()) {
			loadNonActiveStation((String) st2.nextElement());
		}

	}

	private void loadActiveStation(String stationName) {
		if (!activeStationMap.containsKey(stationName)) {
			StationStatusPK stationPk = new StationStatusPK();
			StationStatus station = new StationStatus();
			stationPk.setName(stationName);
			station.setId(stationPk);
			station.setNextPadLife(initialNextPadLife);
			station.setCurrentPadId("");
			activeStationMap.put(stationName, station);
		}
	}

	private void loadNonActiveStation(String stationName) {
		if (!nonActiveStationMap.containsKey(stationName)) {
			StationStatusPK stationPk = new StationStatusPK();
			StationStatus station = new StationStatus();
			stationPk.setName(stationName);
			station.setId(stationPk);
			station.setNextPadLife(initialNextPadLife);
			station.setCurrentPadId("");
			nonActiveStationMap.put(stationName, station);
		}
	}

	private void createConnection() {

		Iterator activeStationIterator = activeStationMap.keySet().iterator();

		while (activeStationIterator.hasNext()) {
			String stationName = (String) activeStationIterator.next();
			createConnectionInDB(stationName);
		}

		Iterator nonActiveStationIterator = nonActiveStationMap.keySet()
				.iterator();

		while (nonActiveStationIterator.hasNext()) {
			String stationName = (String) nonActiveStationIterator.next();
			createConnectionInDB(stationName);
		}
	}

	private void createConnectionInDB(String stationName) {
		DatabaseManager dm = new DatabaseManager();
		List<StationConnection> connectionList = dm
				.listStationConnStationName(stationName);

		if (connectionList.size() == 0) {
			StationConnection stationConnection = new StationConnection();
			stationConnection.setStationName(stationName);
			stationConnection.setConnect(false);
			stationConnection
					.setComment("New Station, please start the connection when ready.");

			EntityWrapper<StationConnection> db = new EntityWrapper<StationConnection>();
			db.add(stationConnection);
			db.commit();
		}

		if (connectionList.size() > 0) {
			StationConnection stationConnection = (StationConnection) connectionList
					.get(0);
			
			//connectionMap.put(stationConnection.getStationName(),
			//		stationConnection);
			
			// updateStationGUI(stationConnection, null, null);
			MainGUI.updateConnection(Integer.parseInt(stationName),Constants.STATION_DISCONNECTED);
		}

	}

	public void startBackEnd() {

		try {

			PropertiesLoader.getInstance();

			ComPort comPort = ComPort.getInstance(); 

			loadStationMap();

			createConnection();

			monitor = new MonitorProcessor();
			monitor.startMonitor();
			
			if(PropertiesLoader.getPolyOnOff() ==1){
			 polyPatch = new PolyPatch();
			 polyPatch.startPloy();
			}

			 plcControl = new TaperAdjustProcessor();
			 plcControl.startAdjustTaper();

			 wcsExcel = new WCSExcelProcessor();
	         wcsExcel.startWSCReader();

			 taperAverageProcessor = new TaperAverageExcelProcessor();
			 taperAverageProcessor.startWCSTaperAverage();
			 
			registerReader = new RegisterReader();
			registerReader.startRead();

		} catch (Exception e) {
			List<String> errMsg01 = new ArrayList<String>();
			if (e.getCause() != null)
				errMsg01.add(e.getCause().toString());
			errMsg01.add(e.toString());
			ErrorMessage.displayError(ErrorMessage.CRITICAL_ERROR, true,
					"ERROR", e.getMessage(), errMsg01);
		}
	}

	public static void main(String args[]) {
		TaperController taperController = new TaperController();
		taperController.startBackEnd();
		// taperController.createConnection();

	}

}
